package com.line.myprojectservice.chatserver;

import com.line.myprojectservice.chatserver.initializer.MyChanneInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.concurrent.ImmediateEventExecutor;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;


/**
 * @author Line
 */
@Slf4j
public class ChatServer {

    //创建 DefaultChannelGroup，其将保存所有已经连接的 WebSocket Channel

    private final ChannelGroup channelGroup = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);

    // 使用多Reactor多线程模型，EventLoopGroup相当于线程池，内部维护一个或多个线程（EventLoop），每个EventLoop可处理多个Channel（单线程处理多个IO任务）
    // 创建主线程组EventLoopGroup，专门负责建立连接

    EventLoopGroup bossGroup = new NioEventLoopGroup();
    // 创建子线程组，专门负责IO任务的处理

    EventLoopGroup workGroup = new NioEventLoopGroup();


    private Channel channel;

    public ChannelFuture start(InetSocketAddress address) {

        ServerBootstrap bootstrap = new ServerBootstrap();
        //用于确定排队的连接数。还有其他配置看一下
        bootstrap.option(ChannelOption.SO_BACKLOG, 1024);

        bootstrap.group(workGroup, bossGroup)
//                .option(ChannelOption.SO_BACKLOG, 128)
//                .childOption(ChannelOption.TCP_NODELAY, true)
//                .childOption(ChannelOption.SO_KEEPALIVE, true)
//                .handler(new LoggingHandler(LogLevel.TRACE))
                .channel(NioServerSocketChannel.class)
                .childHandler(new MyChanneInitializer());
        ChannelFuture future = bootstrap.bind(address);
        future.syncUninterruptibly();

        log.info(ChatServer.class + " 启动正在监听： " + future.channel().localAddress());


        channel = future.channel();
        return future;
    }


    public void start0(int port) {

        final ChatServer endpoint = new ChatServer();
        ChannelFuture future = endpoint.start(new InetSocketAddress(port));

        //优雅关闭，后续改进
        Runtime.getRuntime().addShutdownHook(new Thread(endpoint::destroy));
        //禁止中断的阻塞
        future.channel().closeFuture().syncUninterruptibly();
    }

//
//    /**
//     * 在创建Bean时运行
//     * 需要开启一个新的线程来执行netty server 服务器
//     */
//    @PostConstruct()
//    public void init() {
//        new Thread(() -> {
//            try {
//                start();
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }).start();
//    }



    /**
     * 处理服务器关闭，并释放所有的资源
     */
    public void destroy() {
        if (channel != null) {
            channel.close();
        }
        channelGroup.close();
        workGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
    }


//
//    /**
//     * 在程序关闭前
//     * 释放资源
//     */
//    @PreDestroy
//    public void destroy() throws InterruptedException {
//        if (bossGroup != null) {
//            bossGroup.shutdownGracefully().sync();
//        }
//        if (workGroup != null) {
//            workGroup.shutdownGracefully().sync();
//        }
//    }


}
